package com.yylending.las.main;

import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import com.tbruyelle.rxpermissions.Permission;
import com.tencent.tinker.lib.tinker.TinkerInstaller;
import com.umeng.analytics.MobclickAgent;
import com.yyfax.common.CLog;
import com.yyfax.infrastructure.PermissionsGrantedHelper;
import com.yyfax.infrastructure.eventbus.EventAgent;
import com.yyfax.infrastructure.mvp.Presenter;
import com.yyfax.infrastructure.mvp.PresenterLoader;
import com.yyfax.infrastructure.statistics.StatService;
import com.yylending.las.Global;
import com.yylending.las.R;
import com.yylending.las.StatIDSet;
import com.yylending.las.YJKD;
import com.yylending.las.authority.rsa.RsaPresenter;
import com.yylending.las.base.BaseActivity;
import com.yylending.las.common.location.LocationPresenter;
import com.yylending.las.common.location.entity.Location;
import com.yylending.las.common.utils.preferenceutils.PreferenceConstants;
import com.yylending.las.common.utils.preferenceutils.PreferenceManager;
import com.yylending.las.common.widgets.CommonDialog;
import com.yylending.las.lending.QuotaEvent;
import com.yylending.las.lending.quota.initdata.InitDataModel;
import com.yylending.las.lending.quota.initdata.InitDataPresenter;
import com.yylending.las.personal.version.UpdateService;
import com.yylending.las.personal.version.VersionPresenter;
import com.yylending.las.tinker.network.TinkerPatchModel;
import com.yylending.las.tinker.network.TinkerPatchPresenter;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import zlc.season.rxdownload.DownloadStatus;
import zlc.season.rxdownload.RxDownload;

import java.io.File;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import static com.yylending.las.tinker.util.Utils.getFileMD5;

/**
 * Created by HenryZhang on 2017/7/18.<br>
 * Copyright © 2017 www.yylending.com. All Rights Reserved.<br><br>
 */
public abstract class MainInnerActivity extends BaseActivity implements
		LocationPresenter.View, VersionPresenter.View, RsaPresenter.View, InitDataPresenter.View, TinkerPatchPresenter.View,
		ActivityCompat.OnRequestPermissionsResultCallback {
	private static final String mTAG = "MainInnerActivity";

	private final static int LOADER_ID_LOCATION = 1;
	private final static int LOADER_ID_UPDATE = 2;
	private final static int LOADER_ID_RSA = 4;
	private final static int LOADER_ID_INIT = 5;
	private final int LOADER_ID_TINKER_PATCH = 11;

	public static final String STAT_VERSIONCode = "stat_versionCode";
	public static final String STAT_CHANNEL = "stat_channel";

	/**
	 * 调用定时事件
	 */
	class TimerEvent {
	}

	private static final int TIMER_TRIGGER_TIME = 60 * 1000; // 60秒后开启循环任务
	private static final int TIMER_INTERVAL_TIME = 60 * 1000; // 1分钟请求一次

	private long mBackPressedTime;

	private Subscription mSubscription;

	/**
	 * 常住地区是否初始化
	 */
	boolean mHadAreaInit = false;
	/**
	 * 选项卡是否初始化
	 */
	boolean mHadOptionInit = false;

	private Timer mTimer;
	private TimerTask mTimerTask;

	private LocationPresenter mLocatePresenter;
	private VersionPresenter mVersionPresenter;
	private RsaPresenter mRsaPresenter;
	private InitDataPresenter mInitPresenter;
	private TinkerPatchPresenter mTinkerPatchPresenter;
	private UpdateService mUpdateService;
	public Location mLocation;

	@Override
	public Loader<Presenter> onCreateLoader(int id, Bundle args) {
		switch (id) {
			case LOADER_ID_LOCATION:
				return new PresenterLoader<>(this, new LocationPresenter.Generator());
			case LOADER_ID_UPDATE:
				return new PresenterLoader<>(this, new VersionPresenter.Generator());
			case LOADER_ID_RSA:
				return new PresenterLoader<>(this, new RsaPresenter.Generator());
			case LOADER_ID_INIT:
				return new PresenterLoader<>(this, new InitDataPresenter.Generator());
			case LOADER_ID_TINKER_PATCH:
				return new PresenterLoader<>(this, new TinkerPatchPresenter.Generator());
			default:
				return null;
		}
	}

	@Override
	public void onLoadFinished(Loader<Presenter> loader, Presenter data, int placeholder) {
		switch (loader.getId()) {
			case LOADER_ID_LOCATION:
				mLocatePresenter = (LocationPresenter) data;
				mLocatePresenter.attach(this);
				PermissionsGrantedHelper.PermissionsEachGranted(mRxPermissions, mGrantedListener, Manifest.permission.ACCESS_COARSE_LOCATION);
				break;
			case LOADER_ID_UPDATE:
				mVersionPresenter = (VersionPresenter) data;
				mVersionPresenter.attach(this);
				mVersionPresenter.checkVersion(false);
				break;
			case LOADER_ID_RSA:
				mRsaPresenter = (RsaPresenter) data;
				mRsaPresenter.attach(this);
				mRsaPresenter.getRsaKey();
				break;
			case LOADER_ID_INIT:
				mInitPresenter = (InitDataPresenter) data;
				mInitPresenter.attach(this);
				if (YJKD.login() && !mHadOptionInit) {
					mInitPresenter.getOptionList();
				}
				break;
			case LOADER_ID_TINKER_PATCH:
				mTinkerPatchPresenter = (TinkerPatchPresenter) data;
				mTinkerPatchPresenter.attach(this);
				mTinkerPatchPresenter.getPatch(YJKD.getInstance().getPreferenceManager().getTinkerTimestamp());
				break;
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getSupportLoaderManager().initLoader(LOADER_ID_LOCATION, null, this);
		getSupportLoaderManager().initLoader(LOADER_ID_UPDATE, null, this);
		getSupportLoaderManager().initLoader(LOADER_ID_RSA, null, this);
		getSupportLoaderManager().initLoader(LOADER_ID_INIT, null, this);
		getSupportLoaderManager().initLoader(LOADER_ID_TINKER_PATCH, null, this);
		try {
			PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
			String result = pm.getTinkerResult();
			HashMap<String, String> map = new HashMap<>();
			map.put(STAT_VERSIONCode, Global.VERSION);
			map.put(STAT_CHANNEL, YJKD.channel);
			if ("success".equals(result)) {
				MobclickAgent.onEvent(this, StatIDSet.EVENT_ID_TINKER_SUCCESS, map);
			} else if ("fail".equals(result)) {
				MobclickAgent.onEvent(this, StatIDSet.EVENT_ID_TINKER_FAILED, map);
			}
			YJKD.saveTinkerResult("");
		} catch (Exception e) {

		}

	}

	@Override
	protected void onStart() {
		super.onStart();
		Global.setThirdPartyPageOpenedFlag(false);
		mTimer = new Timer();
		mTimerTask = new TimerTask() {
			@Override
			public void run() {
				EventAgent.post(new TimerEvent());
			}
		};
		mTimer.schedule(mTimerTask, TIMER_TRIGGER_TIME, TIMER_INTERVAL_TIME);

		if (YJKD.login() && !mHadOptionInit && mInitPresenter != null) {
			mInitPresenter.getOptionList();
		}
	}

	/**
	 * 定时器回调，目前只做定时获取账号状态，子类必须添加@Subscribe(threadMode = ThreadMode.MAIN)
	 */
	@Subscribe(threadMode = ThreadMode.MAIN)
	public abstract void onTimerEvent(TimerEvent timerEvent);

	@Override
	protected void onStop() {
		super.onStop();
		if (mTimer != null) {
			mTimer.cancel();
			mTimer.purge();
			mTimer = null;
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (null != mUpdateService) {
			mUpdateService.closeDialog();
		}

		if (mTimer != null) {
			mTimer.cancel();
			mTimer.purge();
			mTimer = null;
		}

		getSupportLoaderManager().destroyLoader(LOADER_ID_LOCATION);
		getSupportLoaderManager().destroyLoader(LOADER_ID_UPDATE);
		getSupportLoaderManager().destroyLoader(LOADER_ID_RSA);
		getSupportLoaderManager().destroyLoader(LOADER_ID_INIT);
		getSupportLoaderManager().destroyLoader(LOADER_ID_TINKER_PATCH);

		if (mSubscription != null && !mSubscription.isUnsubscribed()) {
			mSubscription.unsubscribe();
		}
	}

	@Override
	public void initOptionsSuccess(InitDataModel.Options options) {
		mHadOptionInit = true;
	}

	@Override
	public void initOptionsFail(String msg) {
		mHadOptionInit = false;
	}

	@Override
	public void onBackPressed() {
		CLog.i(mTAG, "主界面返回键");
		long curTime = SystemClock.uptimeMillis();
		if ((curTime - mBackPressedTime) < (3 * 1000)) {
			PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
			MobclickAgent.onKillProcess(this);
			if (pm.getTinkerNeedRestart()) {
				finish();//这里如果不写这句会闪屏，如果把finish提到前面，担心出现极端情况pm被释放掉
				System.exit(0);
			} else {
				finish();
			}
		} else {
			mBackPressedTime = curTime;
			showToast(getString(R.string.tip_double_click_exit, getString(R.string.app_name)));
		}
	}

	private PermissionsGrantedHelper.PermissionsGrantedListener mGrantedListener = new PermissionsGrantedHelper.PermissionsGrantedListener() {
		@Override
		public void permissionsEachGrantedResult(Permission permission) {
			switch (permission.name) {
				case Manifest.permission.ACCESS_COARSE_LOCATION:
					if (permission.granted) {
						startLocation();
					} else {//权限被禁止
						showNeedLocationPermission();
					}
					break;
				default:
					break;
			}
		}

		@Override
		public void PermissionsAllGrantedResult(boolean granted, int requestCode) {
		}
	};

	private void showNeedLocationPermission(){
		showTwoBtnDialog(getString(R.string.location_permission_hint, getString(R.string.app_name)), getString(R.string.go_to_settings), getString(R.string.cancel), new CommonDialog.ButtonClickListener() {
			@Override
			public void onCancel(CommonDialog dialog) {
				dialog.dismiss();
			}

			@Override
			public void onConfirm(CommonDialog dialog) {
				//忽略手势密码
				Global.setThirdPartyPageOpenedFlag(true);
				Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
				intent.setData(Uri.parse("package:" + getPackageName()));
				startActivity(intent);
				dialog.dismiss();
			}
		}, true);
	}

	private void startLocation() {
		if (null != mLocatePresenter) {
			mLocatePresenter.startLocation(false);
		}
	}

	@Override
	public void onLocateSuccess(Location location) {
		CLog.i(mTAG, "定位成功=" + location.latitude + " * " + location.longitude);
		mLocation = location;
		EventAgent.post(new QuotaEvent.LocateSuccessEvent(QuotaEvent.LocateSuccessEvent.QUOTA_LOCATE_SUCCESS, mLocation));
	}

	@Override
	public void onLocateFail(boolean noPermission) {
		CLog.i(mTAG, "定位失败");
		/*if (NetworkUtils.isNetworkAvailable(this)) {
			showToast(R.string.locate_need_retry);
			//PermissionsGrantedHelper.PermissionsEachGranted(mRxPermissions, mGrantedListener, Manifest.permission.ACCESS_COARSE_LOCATION);
		} else {
			showToast(R.string.locate_error_due_to_network);
		}*/
	}

	@Override
	public void showDialog() {
		showLoading(true);
	}

	@Override
	public void dismissDialog() {
		dismissLoading();
	}

	@Override
	public void hasNewVersion(boolean forceUpdate, String url, String content, String title) {
		if (!forceUpdate && !UpdateService.isNeedCheckUpdate()) {
			return;
		}

		// TODO: 2017/5/3  升级弹框及处理
		try {//todo 临时解决，点击退出应用crash
			mUpdateService = new UpdateService();
			mUpdateService.showUpdateDialog(this, forceUpdate, url, content, title);
		} catch (Exception e) {
			CLog.e(mTAG, e.getMessage());
		}
	}

	@Override
	public void isNewestVersion() {
	}

	@Override
	public void getPatchSuccess(TinkerPatchModel.ResultBean resultBean) {
		if (canLoadPatch(resultBean)) {
			start(resultBean);
		}
	}

	public boolean canLoadPatch(TinkerPatchModel.ResultBean resultBean) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		if (!TextUtils.isEmpty(Global.VERSION) && !TextUtils.isEmpty(resultBean.versionCode) && !TextUtils.isEmpty(resultBean.md5)
				&& !TextUtils.isEmpty(resultBean.url) && Global.VERSION.equals(resultBean.versionCode)
				&& (pm.getTinkerTimestamp() < resultBean.timestamp || !pm.getTinkerUrl().equals(resultBean.url) || !pm.getTinkerDownLoadCompleted())) {
			return true;
		}
		return false;
	}

	@Override
	public void getPatchFailed() {
		HashMap<String, String> map = new HashMap<>();
		map.put("", "");
		StatService.onEvent(this, "TinkerPatch", map);
	}

	public void saveTinkerMessage(TinkerPatchModel.ResultBean resultBean) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		pm.savePreference(PreferenceConstants.TINKER_TIME_STAMP, resultBean.timestamp);
		pm.savePreference(PreferenceConstants.TINKER_URL, resultBean.url);
	}

	public void saveTinkerDownLoadCompleted(boolean isCompleted) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		pm.savePreference(PreferenceConstants.TINKER_DOWNLOAD_COMPLETED, isCompleted);
	}

	private void start(final TinkerPatchModel.ResultBean resultBean) {
		mSubscription = RxDownload.getInstance()
				.download(resultBean.url, resultBean.timestamp + ".apk", getFilesDir().getAbsolutePath())
				.subscribeOn(Schedulers.io())
				.observeOn(AndroidSchedulers.mainThread())
				.subscribe(new Subscriber<DownloadStatus>() {
					@Override
					public void onNext(DownloadStatus status) {
					}

					@Override
					public void onError(Throwable e) {
					}

					@Override
					public void onCompleted() {
						saveTinkerMessage(resultBean);
						saveTinkerDownLoadCompleted(true);
						String md5 = getFileMD5(new File(getFilesDir().getAbsolutePath() + "/" + resultBean.timestamp + ".apk"));
						if (resultBean.md5.equals(md5)) {
							TinkerInstaller.onReceiveUpgradePatch(YJKD.app(), getFilesDir().getAbsolutePath() + "/" + resultBean.timestamp + ".apk");
						}
					}
				});
	}
}
